Background

This is the flow cytometry and CFU data for Cg, Sc, Kl. Cg, Sc, Kl treated with 0-1M H2O2 are stained with Fungalight 1, run through flow and plated for CFU (details in HT’s ELN). Goal is to correlate Flow vs CFU and generate graphs for figure 3.

require(tidyverse)
require(flowCore)
require(flowClust)
require(openCyto)
require(ggcyto)
require(cowplot)

Import data

data.path = "/Volumes/rdss_bhe2/User/Hanxi Tang/Flow Cytometry/092923-FungaLight-Cgla-analysis/"
fs <- read.flowSet(path = data.path, transformation = FALSE,  # the original values are already linearized. 
                   emptyValue = FALSE,  alter.names = TRUE,   # change parameter names to R format
                   column.pattern = ".H|FSC|SSC") # only load the height variables for the fluorescent parameters
fs0 <- fs # make a copy of the original data in case of corruption

Specify the flowSet phenoData

source("../00-shared/script/20220326-simplify-names-subroutine.R")
oriNames <- sampleNames(fs)
tmp <- str_split(oriNames, pattern = "_", simplify = TRUE)[,c(1, 5)] 
colnames(tmp) <- c("date", "treat") 
sample <- data.frame(tmp) %>% 
  mutate(rep = ifelse(str_sub(treat, 1, 1) == "B", "B", "A"),
         treat = gsub(".fcs", "", treat) %>% gsub("^B ", "", .),
         H2O2 = case_match(treat,
                             "1M" ~ "1000",
                             "Mock" ~ "0",
                             .default = treat),
         H2O2 = factor(H2O2, levels = sort(unique(as.numeric(H2O2)))),
         name = paste(date, rep, H2O2, "mM", sep = "_"))
rownames(sample) <- oriNames
pData(fs) <- sample

Exploratory Data Analysis

Let’s take one dataset and visualize the changes in the various parameters

# define the rectangular gate
cell.filter <- rectangleGate(filterId = "cell", 
                             "FSC.H" = c(125E3, 100E4),
                             "SSC.H" = c(0, 750E3))

Plot all sets

for(set in sets){
  sub <- fs[pData(fs)$set == set]
  # constructor for a list of filters
  #cell.gates <- sapply(sampleNames(fs), function(sn)cell.filter)
  p1 <- ggcyto(sub, aes(x = "FSC.H", y = "SSC.H")) + geom_hex(bins = 80) + 
    geom_gate(cell.filter) +
    facet_wrap(~H2O2, labeller = "label_both") + theme_minimal() +
    labs(title = set) +
    scale_y_continuous(name = "SSC.H (x1000)", labels = function(l) {l/1000}) + 
    scale_x_continuous(name = "FSC.H (x1000)", labels = function(l) {l/1000})
  print(p1)
}

Two populations are visible in the FSC:SSC plot. The minor population with smaller SSC values are more prominent in the more severely stressed cells.

Try Identifying the two clusters

tmp.dat <- fs[pData(fs)$set == "091523A" & pData(fs)$H2O2 == 8][[1]]
tmp.res <- flowClust(
  tmp.dat,
  varNames = c("FSC.H", "SSC.H"),
  K = 2,
  B = 500
  )
Using the serial version of flowClust
summary(tmp.res)
** Experiment Information ** 
Experiment name: Flow Experiment 
Variables used: FSC.H SSC.H 
** Clustering Summary ** 
Number of clusters: 2 
Proportions: 0.7342262 0.2657738 
** Transformation Parameter ** 
lambda: 0.2889299 
** Information Criteria ** 
Log likelihood: -525766.8 
BIC: -1051653 
ICL: -1057529 
** Data Quality ** 
Number of points filtered from above: 0 (0%)
Number of points filtered from below: 0 (0%)
Rule of identifying outliers: 90% quantile
Number of outliers: 999 (4.82%)
Uncertainty summary: 
def.par <- par(no.readonly = TRUE) # save defaults, for resetting...
layout(matrix(c(1,2), ncol = 2))   # divide the figure into two columns
plot(tmp.res, data = tmp.dat, level = 0.8, z.cutoff = 0)
Rule of identifying outliers: 80% quantile
plot(density(tmp.res, data = sub[[4]]), type = "image")
par(def.par)

Let’s split the two populations and compare their fluorescence levels

# creates a filter object to store all settings, but doesn't perform the clustering
tmp.filter <- tmixFilter(filterId = "fsc-ssc", parameters = c("FSC.H", "SSC.H"), K = 2, B = 500)
# implement the actual clustering 
tmp.res2 <- filter(tmp.dat, tmp.filter)
The prior specification has no effect when usePrior=no
Using the serial version of flowClust
tmp.split <- split(tmp.dat, tmp.res2, population = list(ssc.h = 1, ssc.l = 2)) %>% as("flowSet")
# get the MFI for each subset
tmp.median <- fsApply(tmp.split, each_col, median)
tmp.median
       FSC.A    SSC.A  FSC.H    SSC.H BL1.H BL3.H FSC.W SSC.W
ssc.h 381458 283287.0 376180 277454.0   480   172    83    83
ssc.l 337802 150177.5 338860 149218.5   294  1159    81    79
ggcyto(tmp.split, aes(x = "FSC.H", y = "SSC.H")) + geom_hex(bins = 80) + theme_minimal()

ggcyto(tmp.split, aes(x = "BL1.H", y = "BL3.H")) + geom_hex(bins = 80) + scale_x_logicle() + scale_y_logicle() +
  theme_minimal()

Interestingly, the SSC High population appear to be live and SSC low population are mostly dead Also of interest is the presence of a subpopulation with very low staining by FungaLight. This population is mostly in the SSC-high, thus live portion of the sample.

To examine the low-staining pop further, I will make a gate on BL1.H and BL3.H

unstained.filter <- rectangleGate(filterId = "unstained", 
                                  list("BL1.H" = c(0, 100),
                                       "BL3.H" = c(0, 100)))
unstained.res <- filter(tmp.dat, unstained.filter)
unstained.pop <- split(tmp.dat, unstained.res) %>% as("flowSet")
ggcyto(unstained.pop, aes(x = "FSC.H")) + geom_density(aes(color = factor(name)), linewidth = 1.5) + 
  scale_color_manual("Unstained", values = c("unstained-" = "gray20", "unstained+" = "red")) +
  facet_wrap(~NULL) + theme_minimal(base_size = 16)

The unstained population of events seem to be a bit smaller in size compared with the stained population. wonder if this has to do with a transient population of cells with physiological characteristics that make them both smaller and less permeable to both dyes.

for(set in sets){
  sub <- fs[pData(fs)$set == set]
  # constructor for a list of filters
  #cell.gates <- sapply(sampleNames(fs), function(sn)cell.filter)
  p2 <- ggcyto(sub, aes(x = BL1.H, y = BL3.H)) + 
    geom_hex(aes(fill = after_stat(ncount)), bins = 80) + 
    facet_wrap(~H2O2, labeller = "label_both") +
    scale_y_logicle() + scale_x_logicle() +
    labs(title = set) +
    theme_minimal()
  print(p2)
}

We can observe some trends with increasing H2O2 severity, such as an increase in the dead population (top left), more cells exhibiting a higher green and red within the “live” population, possibly due to increased permeability to SYTO9, which is much more fluorescent than PI. Eventually, the population does migrate to the dead gate. Despite these useful trends however, there is a lot of run-to-run variability, to the point where confident assessment of the patterns is not possible.

LS0tCnRpdGxlOiAiRmlnIDMgR3JhcGhzIgphdXRob3I6IEJpbiBIZSwgb3JpZ2luYWxseSBieSBIYW54aSBUYW5nCmRhdGU6ICIyMDIzLTA5LTMwICh1cGRhdGVkIGByIFN5cy5EYXRlKClgKSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogY2VydWxlYW4KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIGNvZGVfZm9sZGluZzogaGlkZQotLS0KCiMgQmFja2dyb3VuZApUaGlzIGlzIHRoZSBmbG93IGN5dG9tZXRyeSBhbmQgQ0ZVIGRhdGEgZm9yIENnLCBTYywgS2wuIENnLCBTYywgS2wgdHJlYXRlZCB3aXRoIDAtMU0gSDJPMiBhcmUgc3RhaW5lZCB3aXRoIEZ1bmdhbGlnaHQgMSwgcnVuIHRocm91Z2ggZmxvdyBhbmQgcGxhdGVkIGZvciBDRlUgKGRldGFpbHMgaW4gSFQncyBFTE4pLiBHb2FsIGlzIHRvIGNvcnJlbGF0ZSBGbG93IHZzIENGVSBhbmQgZ2VuZXJhdGUgZ3JhcGhzIGZvciBmaWd1cmUgMy4KCmBgYHtyIHNldHVwLCBtZXNzYWdlPUZBTFNFfQpyZXF1aXJlKHRpZHl2ZXJzZSkKcmVxdWlyZShmbG93Q29yZSkKcmVxdWlyZShmbG93Q2x1c3QpCnJlcXVpcmUob3BlbkN5dG8pCnJlcXVpcmUoZ2djeXRvKQpyZXF1aXJlKGNvd3Bsb3QpCmBgYAoKIyBJbXBvcnQgZGF0YQpgYGB7cn0KZGF0YS5wYXRoID0gIi9Wb2x1bWVzL3Jkc3NfYmhlMi9Vc2VyL0hhbnhpIFRhbmcvRmxvdyBDeXRvbWV0cnkvMDkyOTIzLUZ1bmdhTGlnaHQtQ2dsYS1hbmFseXNpcy8iCmZzIDwtIHJlYWQuZmxvd1NldChwYXRoID0gZGF0YS5wYXRoLCB0cmFuc2Zvcm1hdGlvbiA9IEZBTFNFLCAgIyB0aGUgb3JpZ2luYWwgdmFsdWVzIGFyZSBhbHJlYWR5IGxpbmVhcml6ZWQuIAogICAgICAgICAgICAgICAgICAgZW1wdHlWYWx1ZSA9IEZBTFNFLCAgYWx0ZXIubmFtZXMgPSBUUlVFLCAgICMgY2hhbmdlIHBhcmFtZXRlciBuYW1lcyB0byBSIGZvcm1hdAogICAgICAgICAgICAgICAgICAgY29sdW1uLnBhdHRlcm4gPSAiLkh8RlNDfFNTQyIpICMgb25seSBsb2FkIHRoZSBoZWlnaHQgdmFyaWFibGVzIGZvciB0aGUgZmx1b3Jlc2NlbnQgcGFyYW1ldGVycwpmczAgPC0gZnMgIyBtYWtlIGEgY29weSBvZiB0aGUgb3JpZ2luYWwgZGF0YSBpbiBjYXNlIG9mIGNvcnJ1cHRpb24KYGBgCgpTcGVjaWZ5IHRoZSBmbG93U2V0IHBoZW5vRGF0YQpgYGB7cn0Kc291cmNlKCIuLi8wMC1zaGFyZWQvc2NyaXB0LzIwMjIwMzI2LXNpbXBsaWZ5LW5hbWVzLXN1YnJvdXRpbmUuUiIpCm9yaU5hbWVzIDwtIHNhbXBsZU5hbWVzKGZzKQp0bXAgPC0gc3RyX3NwbGl0KG9yaU5hbWVzLCBwYXR0ZXJuID0gIl8iLCBzaW1wbGlmeSA9IFRSVUUpWyxjKDEsIDUpXSAKY29sbmFtZXModG1wKSA8LSBjKCJkYXRlIiwgInRyZWF0IikgCnNhbXBsZSA8LSBkYXRhLmZyYW1lKHRtcCkgJT4lIAogIG11dGF0ZShyZXAgPSBpZmVsc2Uoc3RyX3N1Yih0cmVhdCwgMSwgMSkgPT0gIkIiLCAiQiIsICJBIiksCiAgICAgICAgIHRyZWF0ID0gZ3N1YigiLmZjcyIsICIiLCB0cmVhdCkgJT4lIGdzdWIoIl5CICIsICIiLCAuKSwKICAgICAgICAgSDJPMiA9IGNhc2VfbWF0Y2godHJlYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjFNIiB+ICIxMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9jayIgfiAiMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSB0cmVhdCksCiAgICAgICAgIEgyTzIgPSBmYWN0b3IoSDJPMiwgbGV2ZWxzID0gc29ydCh1bmlxdWUoYXMubnVtZXJpYyhIMk8yKSkpKSwKICAgICAgICAgc2V0ID0gZmFjdG9yKHBhc3RlMChkYXRlLCByZXApKSwKICAgICAgICAgbmFtZSA9IHBhc3RlKGRhdGUsIHJlcCwgSDJPMiwgIm1NIiwgc2VwID0gIl8iKSkKcm93bmFtZXMoc2FtcGxlKSA8LSBvcmlOYW1lcwpwRGF0YShmcykgPC0gc2FtcGxlCnNldHMgPC0gbGV2ZWxzKHNhbXBsZSRzZXQpCmBgYAoKIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzCkxldCdzIHRha2Ugb25lIGRhdGFzZXQgYW5kIHZpc3VhbGl6ZSB0aGUgY2hhbmdlcyBpbiB0aGUgdmFyaW91cyBwYXJhbWV0ZXJzCgpgYGB7cn0KIyBkZWZpbmUgdGhlIHJlY3Rhbmd1bGFyIGdhdGUKY2VsbC5maWx0ZXIgPC0gcmVjdGFuZ2xlR2F0ZShmaWx0ZXJJZCA9ICJjZWxsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZTQy5IIiA9IGMoMTI1RTMsIDEwMEU0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU1NDLkgiID0gYygwLCA3NTBFMykpCmBgYAoKUGxvdCBhbGwgc2V0cwpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KcG5nKCJpbWcvMjAyMzA5MzAtIikKZm9yKHNldCBpbiBzZXRzKXsKICBzdWIgPC0gZnNbcERhdGEoZnMpJHNldCA9PSBzZXRdCiAgIyBjb25zdHJ1Y3RvciBmb3IgYSBsaXN0IG9mIGZpbHRlcnMKICAjY2VsbC5nYXRlcyA8LSBzYXBwbHkoc2FtcGxlTmFtZXMoZnMpLCBmdW5jdGlvbihzbiljZWxsLmZpbHRlcikKICBwMSA8LSBnZ2N5dG8oc3ViLCBhZXMoeCA9ICJGU0MuSCIsIHkgPSAiU1NDLkgiKSkgKyBnZW9tX2hleChiaW5zID0gODApICsgCiAgICBnZW9tX2dhdGUoY2VsbC5maWx0ZXIpICsKICAgIGZhY2V0X3dyYXAofkgyTzIsIGxhYmVsbGVyID0gImxhYmVsX2JvdGgiKSArIHRoZW1lX21pbmltYWwoKSArCiAgICBsYWJzKHRpdGxlID0gc2V0KSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJTU0MuSCAoeDEwMDApIiwgbGFiZWxzID0gZnVuY3Rpb24obCkge2wvMTAwMH0pICsgCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJGU0MuSCAoeDEwMDApIiwgbGFiZWxzID0gZnVuY3Rpb24obCkge2wvMTAwMH0pCiAgcHJpbnQocDEpCn0KYGBgCgo+IFR3byBwb3B1bGF0aW9ucyBhcmUgdmlzaWJsZSBpbiB0aGUgRlNDOlNTQyBwbG90LiBUaGUgbWlub3IgcG9wdWxhdGlvbiB3aXRoIHNtYWxsZXIgU1NDIHZhbHVlcyBhcmUgbW9yZSBwcm9taW5lbnQgaW4gdGhlIG1vcmUgc2V2ZXJlbHkgc3RyZXNzZWQgY2VsbHMuCgpUcnkgSWRlbnRpZnlpbmcgdGhlIHR3byBjbHVzdGVycwpgYGB7cn0KdG1wLmRhdCA8LSBmc1twRGF0YShmcykkc2V0ID09ICIwOTE1MjNBIiAmIHBEYXRhKGZzKSRIMk8yID09IDhdW1sxXV0KdG1wLnJlcyA8LSBmbG93Q2x1c3QoCiAgdG1wLmRhdCwKICB2YXJOYW1lcyA9IGMoIkZTQy5IIiwgIlNTQy5IIiksCiAgSyA9IDIsCiAgQiA9IDUwMAogICkKYGBgCgpgYGB7cn0Kc3VtbWFyeSh0bXAucmVzKQpkZWYucGFyIDwtIHBhcihuby5yZWFkb25seSA9IFRSVUUpICMgc2F2ZSBkZWZhdWx0cywgZm9yIHJlc2V0dGluZy4uLgpsYXlvdXQobWF0cml4KGMoMSwyKSwgbmNvbCA9IDIpKSAgICMgZGl2aWRlIHRoZSBmaWd1cmUgaW50byB0d28gY29sdW1ucwpwbG90KHRtcC5yZXMsIGRhdGEgPSB0bXAuZGF0LCBsZXZlbCA9IDAuOCwgei5jdXRvZmYgPSAwKQpwbG90KGRlbnNpdHkodG1wLnJlcywgZGF0YSA9IHN1YltbNF1dKSwgdHlwZSA9ICJpbWFnZSIpCnBhcihkZWYucGFyKQpgYGAKCkxldCdzIHNwbGl0IHRoZSB0d28gcG9wdWxhdGlvbnMgYW5kIGNvbXBhcmUgdGhlaXIgZmx1b3Jlc2NlbmNlIGxldmVscwpgYGB7cn0KIyBjcmVhdGVzIGEgZmlsdGVyIG9iamVjdCB0byBzdG9yZSBhbGwgc2V0dGluZ3MsIGJ1dCBkb2Vzbid0IHBlcmZvcm0gdGhlIGNsdXN0ZXJpbmcKdG1wLmZpbHRlciA8LSB0bWl4RmlsdGVyKGZpbHRlcklkID0gImZzYy1zc2MiLCBwYXJhbWV0ZXJzID0gYygiRlNDLkgiLCAiU1NDLkgiKSwgSyA9IDIsIEIgPSA1MDApCiMgaW1wbGVtZW50IHRoZSBhY3R1YWwgY2x1c3RlcmluZyAKdG1wLnJlczIgPC0gZmlsdGVyKHRtcC5kYXQsIHRtcC5maWx0ZXIpCmBgYAoKYGBge3J9CnRtcC5zcGxpdCA8LSBzcGxpdCh0bXAuZGF0LCB0bXAucmVzMiwgcG9wdWxhdGlvbiA9IGxpc3Qoc3NjLmggPSAxLCBzc2MubCA9IDIpKSAlPiUgYXMoImZsb3dTZXQiKQojIGdldCB0aGUgTUZJIGZvciBlYWNoIHN1YnNldAp0bXAubWVkaWFuIDwtIGZzQXBwbHkodG1wLnNwbGl0LCBlYWNoX2NvbCwgbWVkaWFuKQp0bXAubWVkaWFuCmdnY3l0byh0bXAuc3BsaXQsIGFlcyh4ID0gIkZTQy5IIiwgeSA9ICJTU0MuSCIpKSArIGdlb21faGV4KGJpbnMgPSA4MCkgKyB0aGVtZV9taW5pbWFsKCkKZ2djeXRvKHRtcC5zcGxpdCwgYWVzKHggPSAiQkwxLkgiLCB5ID0gIkJMMy5IIikpICsgZ2VvbV9oZXgoYmlucyA9IDgwKSArIHNjYWxlX3hfbG9naWNsZSgpICsgc2NhbGVfeV9sb2dpY2xlKCkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKPiBJbnRlcmVzdGluZ2x5LCB0aGUgU1NDIEhpZ2ggcG9wdWxhdGlvbiBhcHBlYXIgdG8gYmUgbGl2ZSBhbmQgU1NDIGxvdyBwb3B1bGF0aW9uIGFyZSBtb3N0bHkgZGVhZAo+IEFsc28gb2YgaW50ZXJlc3QgaXMgdGhlIHByZXNlbmNlIG9mIGEgc3VicG9wdWxhdGlvbiB3aXRoIHZlcnkgbG93IHN0YWluaW5nIGJ5IEZ1bmdhTGlnaHQuIFRoaXMgcG9wdWxhdGlvbiBpcyBtb3N0bHkgaW4gdGhlIFNTQy1oaWdoLCB0aHVzIGxpdmUgcG9ydGlvbiBvZiB0aGUgc2FtcGxlLgoKVG8gZXhhbWluZSB0aGUgbG93LXN0YWluaW5nIHBvcCBmdXJ0aGVyLCBJIHdpbGwgbWFrZSBhIGdhdGUgb24gQkwxLkggYW5kIEJMMy5ICmBgYHtyfQp1bnN0YWluZWQuZmlsdGVyIDwtIHJlY3RhbmdsZUdhdGUoZmlsdGVySWQgPSAidW5zdGFpbmVkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KCJCTDEuSCIgPSBjKDAsIDEwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCTDMuSCIgPSBjKDAsIDEwMCkpKQp1bnN0YWluZWQucmVzIDwtIGZpbHRlcih0bXAuZGF0LCB1bnN0YWluZWQuZmlsdGVyKQp1bnN0YWluZWQucG9wIDwtIHNwbGl0KHRtcC5kYXQsIHVuc3RhaW5lZC5yZXMpICU+JSBhcygiZmxvd1NldCIpCmdnY3l0byh1bnN0YWluZWQucG9wLCBhZXMoeCA9ICJGU0MuSCIpKSArIGdlb21fZGVuc2l0eShhZXMoY29sb3IgPSBmYWN0b3IobmFtZSkpLCBsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKCJVbnN0YWluZWQiLCB2YWx1ZXMgPSBjKCJ1bnN0YWluZWQtIiA9ICJncmF5MjAiLCAidW5zdGFpbmVkKyIgPSAicmVkIikpICsKICBmYWNldF93cmFwKH5OVUxMKSArIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTYpCmBgYAo+IFRoZSB1bnN0YWluZWQgcG9wdWxhdGlvbiBvZiBldmVudHMgc2VlbSB0byBiZSBhIGJpdCBzbWFsbGVyIGluIHNpemUgY29tcGFyZWQgd2l0aCB0aGUgc3RhaW5lZCBwb3B1bGF0aW9uLgo+IHdvbmRlciBpZiB0aGlzIGhhcyB0byBkbyB3aXRoIGEgdHJhbnNpZW50IHBvcHVsYXRpb24gb2YgY2VsbHMgd2l0aCBwaHlzaW9sb2dpY2FsIGNoYXJhY3RlcmlzdGljcwo+IHRoYXQgbWFrZSB0aGVtIGJvdGggc21hbGxlciBhbmQgbGVzcyBwZXJtZWFibGUgdG8gYm90aCBkeWVzLgoKYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9CmZvcihzZXQgaW4gc2V0cyl7CiAgc3ViIDwtIGZzW3BEYXRhKGZzKSRzZXQgPT0gc2V0XQogICMgY29uc3RydWN0b3IgZm9yIGEgbGlzdCBvZiBmaWx0ZXJzCiAgI2NlbGwuZ2F0ZXMgPC0gc2FwcGx5KHNhbXBsZU5hbWVzKGZzKSwgZnVuY3Rpb24oc24pY2VsbC5maWx0ZXIpCiAgcDIgPC0gZ2djeXRvKHN1YiwgYWVzKHggPSBCTDEuSCwgeSA9IEJMMy5IKSkgKyAKICAgIGdlb21faGV4KGFlcyhmaWxsID0gYWZ0ZXJfc3RhdChuY291bnQpKSwgYmlucyA9IDgwKSArIAogICAgZmFjZXRfd3JhcCh+SDJPMiwgbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpICsKICAgIHNjYWxlX3lfbG9naWNsZSgpICsgc2NhbGVfeF9sb2dpY2xlKCkgKwogICAgbGFicyh0aXRsZSA9IHNldCkgKwogICAgdGhlbWVfbWluaW1hbCgpCiAgcHJpbnQocDIpCn0KYGBgCj4gV2UgY2FuIG9ic2VydmUgc29tZSB0cmVuZHMgd2l0aCBpbmNyZWFzaW5nIEgyTzIgc2V2ZXJpdHksIHN1Y2ggYXMgYW4gaW5jcmVhc2UgaW4gdGhlIAo+IGRlYWQgcG9wdWxhdGlvbiAodG9wIGxlZnQpLCBtb3JlIGNlbGxzIGV4aGliaXRpbmcgYSBoaWdoZXIgZ3JlZW4gYW5kIHJlZCB3aXRoaW4gdGhlICJsaXZlIgo+IHBvcHVsYXRpb24sIHBvc3NpYmx5IGR1ZSB0byBpbmNyZWFzZWQgcGVybWVhYmlsaXR5IHRvIFNZVE85LCB3aGljaCBpcyBtdWNoIG1vcmUgZmx1b3Jlc2NlbnQKPiB0aGFuIFBJLiBFdmVudHVhbGx5LCB0aGUgcG9wdWxhdGlvbiBkb2VzIG1pZ3JhdGUgdG8gdGhlIGRlYWQgZ2F0ZS4gRGVzcGl0ZSB0aGVzZSB1c2VmdWwgdHJlbmRzCj4gaG93ZXZlciwgdGhlcmUgaXMgYSBsb3Qgb2YgcnVuLXRvLXJ1biB2YXJpYWJpbGl0eSwgdG8gdGhlIHBvaW50IHdoZXJlIGNvbmZpZGVudCBhc3Nlc3NtZW50IG9mCj4gdGhlIHBhdHRlcm5zIGlzIG5vdCBwb3NzaWJsZS4KCg==